/**
在 React 中，非父子组件之间的通信可以通过 Context API 实现。Context 提供了一种方式，可以在组件树中传递数据，而不必通过每一个层级的 props。这种方式特别适合于共享一些全局的数据，比如主题、用户信息、语言设置等。
  1. Context 的基本概念
  - Context 是一个用于共享数据的 React 组件，可以在组件树中传递数据，而无需通过 props 一层层传递。
  - Context 主要由两个部分组成：Provider 和 Consumer。

  2. 创建 Context
  使用  `React.createContext()`  创建一个 Context 对象：
  jsx
  const MyContext = React.createContext();
  3. 提供数据

  使用 Provider 组件来提供数据。Provider 组件接受一个  `value`  属性，这个属性就是要传递的数据。
  jsx
  const App = () => {
    const user = { name: 'John', age: 30 };

    return (
      <MyContext.Provider value={user}>
        <Child />
      </MyContext.Provider>
    );
  };
  4. 消费数据
  使用 Consumer 组件或者  `useContext`  Hook 来消费数据。Consumer 组件需要一个函数作为子组件，函数的参数是 Provider 提供的  `value` 。

   使用 Consumer：
  jsx
  const Child = () => {
    return (
      <MyContext.Consumer>
        {(user) => <div>{user.name}</div>}
      </MyContext.Consumer>
    );
  };
   使用  `useContext`  Hook：
  jsx
  import { useContext } from 'react';

  const Child = () => {
    const user = useContext(MyContext);
    return <div>{user.name}</div>;
  };
  5. 注意事项
  - 性能：当 Provider 的  `value`  改变时，所有使用了这个 Context 的组件都会重新渲染，可能会影响性能。因此，建议将频繁变化的数据放在状态管理库中（如 Redux）或使用其他优化手段。
  - 嵌套：Context 可以嵌套使用，允许你在不同的层级提供不同的数据。
  - 可读性：使用 Context API 可以减少 props 的传递，使得组件的结构更加清晰，但也可能使得数据流动的路径不那么明显，因此需要合理使用。

  6. 总结
  React Context API 提供了一种方便的方式来实现非父子组件之间的通信。通过 Provider 和 Consumer，开发者可以在组件树中传递数据，而不必通过每个层级的 props。这种方式适合于共享全局数据，增强了组件的灵活性和可维护性。
 */
import React, { Component } from 'react'
import Home from './c-cpns/Home'

import ThemeContext from './context/theme-context'
import UserContext from './context/user-context'
import Profile from './c-cpns/Profile'

export default class App extends Component {
  constructor() {
    super()
    this.state = {
      info: {
        color: 'red',
        size: '20px',
        name: 'context-info'
      }
    }
  }
  
  render() {
    const { info } = this.state
    
    return (
      <div>
        <h3>通过Context中Provider中value属性为后代提供数据 </h3>
        <ThemeContext.Provider value={{
          color: 'red',
          size: '20px'
        }}>
          <UserContext.Provider value={{
            nickname: 'React.createContext name',
            level: 99
          }}>
            <Home {...info}/>
          </UserContext.Provider>
        </ThemeContext.Provider>
        <Profile/>
      </div>
    )
  }
}
